package com.superzlc.vcontroller;

import java.io.IOException;
import java.util.concurrent.BlockingQueue;

import com.superzlc.vcontroller.CtrlAllView.CtrlEvent;
import com.superzlc.vcontroller.message.client.BroadcastClient;
import com.superzlc.vcontroller.message.client.Constants;
import com.superzlc.vcontroller.message.client.MessageClient;
import com.superzlc.vcontroller.message.client.MessageOp;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends Activity {

	protected void onCreate(Bundle savedInstanceState) {

		// 隐藏标题栏
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		// 隐藏状态栏
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);

		super.onCreate(savedInstanceState);
		ctrlAllView = new CtrlAllView(this);
		this.setContentView(ctrlAllView);

		threadMessage.start();

	}

	CtrlAllView ctrlAllView;

	static class MarkCtrl {
		int[] markasix = new int[8];
		int[] markbtn = new int[32];
		void clean() {
			for(int i = 0; i < markbtn.length; i++)
				markbtn[i] = 0;
			for(int i = 0; i < markasix.length; i++)
				markasix[i] = 0;
		}
		boolean find(CtrlEvent e) {
			if (e.type == CtrlEvent.type_asix)
				return markasix[e.idx] == 1;
			else
				return markbtn[e.idx] == 1;
		}
		void add(CtrlEvent e) {
			if (e.type == CtrlEvent.type_asix)
				markasix[e.idx] = 1;
			else
				markbtn[e.idx] = 1;
		}
		void remove(CtrlEvent e) {
			if (e.type == CtrlEvent.type_asix)
				markasix[e.idx] = 0;
			else
				markbtn[e.idx] = 0;
		}
	}

	MessageClient msgclient;
	MessageOp.VJoyPackage pkg1 = new MessageOp.VJoyPackage();
	MessageOp.VJoyPackage pkg2 = new MessageOp.VJoyPackage();
	MessageOp.VJoyPackage pkg = pkg1, pkgBak = pkg2;

	Thread threadMessage = new Thread() {
		public void run() {
			while(true) {
				String ip = new BroadcastClient().requestIp();
				if (ip == null) {
					try {
						Thread.sleep(3000);
					} catch (InterruptedException e) {
						break;
					}
				} else {
					Log.i("vjoy", "获取到服务端IP地址：" + ip);
					msgclient = new MessageClient(ip, Constants.PORT_FOR_MESSAGE);
					break;
				}
			}
			msgclient.startup();
			if (!msgclient.isStarted())
				return;
			Log.i("vjoy", "开始发送数据包到服务端供vjoy使用");
			loop();
		}
	};


	public void onDestroy() {
		if (msgclient != null && msgclient.isStarted())
			msgclient.shutdown();
	}


	boolean equals(MessageOp.VJoyPackage pkg1, MessageOp.VJoyPackage pkg2) {
		// 按最后变动id判断
		int idx = ctrlAllView.lastChangedAsixIdx;
		if (pkg1.getAsix(idx) != pkg2.getAsix(idx))
			return false;
		idx = ctrlAllView.lastChangedBtnIdx;
		if (pkg1.getBtnPressed(idx) != pkg2.getBtnPressed(idx))
			return false;
		// 那么这段主要发生在刚停止控制的3秒里
		for (int i = 0; i < 8; i++) {
			if (pkg1.getAsix(i) != pkg2.getAsix(i)) {
				return false;
			}
		}
		for (int i = 0; i < 32; i++) {
			if (pkg1.getBtnPressed(i) != pkg2.getBtnPressed(i)) {
				return false;
			}
		}
		return true;
	}

	long sleep = 5;
	int countEmptyOp = 0;
	void loop() {
		while(true) {
			long timeStart = System.currentTimeMillis();
			try {
				Thread.sleep(sleep);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			// 判断时间，3s没变化就认为没变，不用处理
			if (System.currentTimeMillis() - ctrlAllView.lasttime > 1000 * 3) {
			//	sleep = 100; // 加上sleep顺便调整休眠时间
				if (countEmptyOp++ > 300) {
					countEmptyOp = 0;
					try {
						msgclient.sendHeardbeat();
					} catch (IOException e) {
						Log.i("vjoy", "发送数据包异常，跳出循环");
						e.printStackTrace();
						break;
					}
				}
				continue;
			} else {
			//	sleep = 10;
			}
			// 备份
			pkgBak = pkg;
			pkg = pkg == pkg1 ? pkg2 : pkg1;
			pkg.setAsix(0, ctrlAllView.getAsixProgress(0));
			pkg.setAsix(1, ctrlAllView.getAsixProgress(1));
			pkg.setAsix(2, ctrlAllView.getAsixProgress(2));
			pkg.setAsix(3, ctrlAllView.getAsixProgress(3));
			pkg.setAsix(4, ctrlAllView.getAsixProgress(4));
			pkg.setAsix(5, ctrlAllView.getAsixProgress(5));
			pkg.setAsix(6, ctrlAllView.getAsixProgress(6));
			pkg.setAsix(7, ctrlAllView.getAsixProgress(7));
			for (int i = 0; i < 32; i++) {
				pkg.setBtn(i, ctrlAllView.getButtonPressed(i));
			}

			// 比较数据有没有修改
			if (this.equals(pkgBak, pkg)) {
				if (countEmptyOp++ > 300) {
					countEmptyOp = 0;
					try {
						msgclient.sendHeardbeat();
					} catch (IOException e) {
						e.printStackTrace();
						break;
					}
				}
				continue;
			}

			// 有修改则发送数据
			try {
				countEmptyOp = 0;
				msgclient.sendData(pkg);
				// Log.i("vjoy", "一圈数据采集发送耗时ms" + (System.currentTimeMillis() - timeStart));
				Log.i("vjoy", "发送数据在 " + System.currentTimeMillis());
			} catch (Exception e4) {
				Log.i("vjoy", "发送数据包异常，跳出循环");
				e4.printStackTrace();
				break;
			}
		}
	}

	void loop2() {

		BlockingQueue<CtrlEvent> q = ctrlAllView.getCtrlEventQueue();
		MarkCtrl mark = new MarkCtrl();
		while(true) {
			try {
				CtrlEvent e = null;
				synchronized(q) {
					e = q.poll();
						if (e == null) {
							q.wait();
							e = q.poll();
						}
				}
				// e
				if (e.type == CtrlEvent.type_asix) {
					pkg.setAsix(e.idx, e.status);
				} else {
					pkg.setBtn(e.idx, e.status == CtrlEvent.status_down);
				}
				CtrlEvent e1 = q.peek();
				if (e1 != null && !e1.equalsSrc(e)) {
					mark.clean();
					mark.add(e);
					e1 = q.poll();
					mark.add(e1);
					// e1
					if (e1.type == CtrlEvent.type_asix) {
						pkg.setAsix(e1.idx, e1.status);
					} else {
						pkg.setBtn(e.idx, e1.status == CtrlEvent.status_down);
					}
					while(true) {
						e1 = q.peek();
						if (e1 == null)
							break;
						if (mark.find(e1))
							break;
						e1 = q.poll();
						// e1
						if (e1.type == CtrlEvent.type_asix) {
							pkg.setAsix(e1.idx, e1.status);
						} else {
							pkg.setBtn(e.idx, e1.status == CtrlEvent.status_down);
						}
					}
				}
				try {
					msgclient.sendData(pkg);
					//Thread.sleep(5);
				} catch (Exception e4) {
					e4.printStackTrace();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	void loop1() {
		while(true) {
//			 Log.i("vjoy", String.format("获取到轴：%d  %d  %d  %d",
//					 ctrlAllView.getAsix(0),
//					 ctrlAllView.getAsix(1),
//					 ctrlAllView.getAsix(2),
//					 ctrlAllView.getAsix(3)));
			pkg.setAsix(0, ctrlAllView.getAsixProgress(0));
			pkg.setAsix(1, ctrlAllView.getAsixProgress(1));
			pkg.setAsix(2, ctrlAllView.getAsixProgress(2));
			pkg.setAsix(3, ctrlAllView.getAsixProgress(3));
			pkg.setAsix(4, ctrlAllView.getAsixProgress(4));
			pkg.setAsix(5, ctrlAllView.getAsixProgress(5));
			pkg.setAsix(6, ctrlAllView.getAsixProgress(6));
			pkg.setAsix(7, ctrlAllView.getAsixProgress(7));

			BlockingQueue<CtrlEvent> q = ctrlAllView.getCtrlEventQueue();
			CtrlEvent e = q.poll();
			if (e != null)
				pkg.setBtn(e.idx, e.status == CtrlEvent.status_down);
			CtrlEvent e1 = q.peek();
			if (e1 != null && e1.idx != e.idx) {
				e1 = q.poll();
				pkg.setBtn(e1.idx, e1.status == CtrlEvent.status_down);
				int[] tt = new int[32];
				tt[e.idx] = 1;
				tt[e1.idx] = 1;
				while(true) {
					CtrlEvent e2 = q.peek();
					if (e2 == null)
						break;
					if (tt[e2.idx] == 1)
						break;
					tt[e2.idx] = 1;
					e2 = q.poll();
					pkg.setBtn(e2.idx, e2.status == CtrlEvent.status_down);
				}
			}
			try {
				msgclient.sendData(pkg);
				Thread.sleep(5);
			} catch (Exception e4) {
				e4.printStackTrace();
			}
		}
	}

}
